from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP
import os, sys, io, asyncio
import json
import requests

# Initialize FastMCP server
mcp = FastMCP("file_read")

# Constants
USER_AGENT = "file_read-app/1.0"
DATA_FOLDER = "../data"
SANDBOX_URL = 'http://127.0.0.1:6677/run'


def make_code_request(code: str):
    res = requests.post(url=SANDBOX_URL, json={'code': code})
    out = json.loads(res.text)
    out = out['output']
    return out


def get_file_tree_json(folder_path):
    """
    获取文件夹下的文件树结构，并返回 JSON 格式字符串。

    :param folder_path: 文件夹路径
    :return: JSON 格式的文件树结构（字符串）
    """
    def build_tree(current_path):
        """递归构建文件树"""
        tree = {"name": os.path.basename(current_path), "type": "folder", "children": []}

        try:
            contents = os.listdir(current_path)
        except PermissionError:
            tree["error"] = "Permission denied"
            return tree
        except FileNotFoundError:
            tree["error"] = "Folder not found"
            return tree

        for item in sorted(contents):
            item_path = os.path.join(current_path, item)
            if os.path.isdir(item_path):
                # 如果是文件夹，递归处理
                tree["children"].append(build_tree(item_path))
            else:
                # 如果是文件，添加到 children 中
                tree["children"].append({"name": item, "type": "file"})

        return tree

    # 构建文件树
    file_tree = build_tree(folder_path)

    # 将文件树转换为 JSON 格式字符串
    return json.dumps(file_tree, ensure_ascii=False)


@mcp.tool()
def get_data_file_tree_tool():
    """尽量每次都调用这个工具，它会返回数据库的准确文件树，相对路径都是'data/.....'
    
    Args:
        None
    """
    return get_file_tree_json(DATA_FOLDER)


@mcp.tool()
def execute_python_code(code_string):
    """
    执行字符串形式的 Python 代码，代码最后一定要用print输出，鼓励使用Python代码辅助计算和分析数据。
    已经安装了openpyxl，尽量不要用pandas!
    访问文件时，请根据get_data_file_tree_tool工具返回的文件树信息，注意文件名不要写错，注意相对路径的根是../data/

    :param code_string: 字符串形式的 Python 代码
    :return: print输出结果（如果有）或错误信息
    """
    return make_code_request(code_string)


if __name__ == "__main__":
    # print(get_file_tree_tool())
    mcp.run(transport='stdio')


# uv run file_read.py
